ProbotでGitHubのBotを作成してGlitchにデプロイしてみる
GitHubを使う上で、チームによってローカルルールがある場合があると思います。これをみんなで守るためには、例えば啓蒙活動やレビューで頑張ることも一つの方法ですが、本質的には「そもそもルールを破れない状況を作る」ことが一番大切であるように思えます。
GitHubではBotを作成することができるので、ある程度GitHubの使い方に関するローカルルールをBotによって強制的に守らせることが可能です。
本記事では、「Issueを閉じる際にはラベルとマイルストーンが設定されていなければいけない」といったルールを守らせるためのBotをProbotで作成し、Glitchにデプロイしてみました。
本記事で行うこと
- ProbotによるGitHubのBot作成
- Issueをクローズした際にマイルストーンもしくはラベルが未指定の場合、Issueに注意コメントをつけた上で再度オープンする
- ローカルでProbotによるアプリケーションを起動してテスト
- Glitchにデプロイ
前提条件
- ローカルでNode.jsが動作すること
- 本記事ではv8.11.2で動作確認をしました
各要素の簡単な説明
Probot
ProbotはGitHub Appsを作成するためのフレームワークです。
主な機能として、
- GitHubのWebHookから送信された各イベントに対する処理
- GitHubのAPI実行
を簡潔に記載することができます。
Glitch
Glitchが本質的になんなのかについてはまだいまいち掴めていませんが、本記事ではGitHubと連携可能なエディタ兼Node.jsのPaaSとして使用しています。
ざっと見た感じではGitHubとPaaSの中間のようなサービスに見えますが、詳しくは公式をご覧ください。
参考:Glitch - The community where you'll build the app of your dreams
やってみる
Probot
プロジェクトの作成
以下のコマンドを実行し、Botの準備のための質問にいくつか答えるとProbotによるBotのためのテンプレートが作成されます。
test-inabaの部分には作成したいBotの名前を指定します。
$ npx create-probot-app test-inaba
npx: 226個のパッケージを10.752秒でインストールしました。 Let's create a Probot app! ? **App name:** test-inaba ? **Description of app:** A Probot app ? **Author's full name:** inabajunmr ? **Author's email address:** inabajun.for.regi@gmail.com ? **Homepage:** ? **GitHub user or org name:** inabajunmr ? **Repository name:** test-inaba 〜略〜 added 993 packages in 26.38s Done! Enjoy building your Probot app!
完了すると指定した名前のディレクトリ配下にテンプレートが作成されます。
$ ls -la test-inaba total 672 drwxr-xr-x 15 inabajunmr staff 480 5 28 02:44 . drwxr-xr-x 31 inabajunmr staff 992 5 28 02:44 .. -rw-r--r-- 1 inabajunmr staff 236 5 28 02:44 .env.example -rw-r--r-- 1 inabajunmr staff 56 5 28 02:44 .gitignore -rw-r--r-- 1 inabajunmr staff 81 5 28 02:44 .travis.yml -rw-r--r-- 1 inabajunmr staff 3224 5 28 02:44 CODE_OF_CONDUCT.md -rw-r--r-- 1 inabajunmr staff 1790 5 28 02:44 CONTRIBUTING.md -rw-r--r-- 1 inabajunmr staff 772 5 28 02:44 LICENSE -rw-r--r-- 1 inabajunmr staff 170 5 28 02:44 README.md drwxr-xr-x 2 inabajunmr staff 64 5 28 02:44 etc -rw-r--r-- 1 inabajunmr staff 282 5 28 02:44 index.js drwxr-xr-x 674 inabajunmr staff 21568 5 28 02:44 node_modules -rw-r--r-- 1 inabajunmr staff 304624 5 28 02:44 package-lock.json -rw-r--r-- 1 inabajunmr staff 722 5 28 02:44 package.json drwxr-xr-x 3 inabajunmr staff 96 5 28 02:44 test
Botの設定
テストのためにsmee.ioを利用します。smee.ioで割り当てられたURLをGitHubのWebHookに指定することで、smee.io経由でローカルで起動したアプリケーションでリクエストを受け取ることができます。
Start a new channelをクリックするとWebhook Proxy URLが割り当てられるので、これをメモしておきます。
Register new GitHub Appから新規登録をします。
Webhook URLにsmee.ioで取得したWebhook Proxy URL
を指定し、Webhook
secretにdevelopment
を指定します。
PermissionsにはIssuesのRead&Write
を、Subscribe to eventsにはIssues
を指定します。
前者はBotからGitHubへのアクセス権限で、後者はWebHookを発火させるEventの指定となります。 作成後のページにIDが表示されるので、こちらもメモしておきます。
最後に、Generate a private keyから秘密鍵を生成し、プロジェクトのディレクトリ直下に配置します。
作成したらnpx create-probot-app
で作成したディレクトリの.env.example
を.env
にコピーし、編集します。
APP_IDにGitHubで取得したIDを、WEBHOOK_PROXY_URLにはsmee.ioで取得したURLを指定します。
$ cp .env.example .env $ vi .env $ cat .env APP_ID=12729 WEBHOOK_SECRET=development LOG_LEVEL=debug WEBHOOK_PROXY_URL=https://smee.io/XXXXXXXX
Botの動作を編集します。index.jsを以下に修正します。
module.exports = (robot) => { // WebHookによって発火するイベントを定義(IssueのClose時に動作) robot.on('issues.closed', async context => { const exist_label = context.payload.issue.labels.length != 0; const exist_milestone = context.payload.issue.milestone != ''; if (exist_label && exist_milestone) { // ラベルとマイルストーンが設定されていれば何もしない return; } const comment = context.issue({body: 'You must add milestone and label!'}) // Issueにコメントを追加 context.github.issues.createComment(comment) // Issueをオープンする const open = context.issue({state: 'open'}) context.github.issues.edit(open) }) }
コメントの通りですが、構造的には「GitHubに対して何をすると、何が起きるか」です。 上記ではIssueが閉じたタイミングでスクリプトを実行し、ラベルとマイルストーンが設定されていなければIssueに「You must add milestone and label!」とコメントし、IssueをOpenします。
「何をすると」の部分、つまりWebHookの定義についてはこちらを参照してください。 例えばIssueそのものに対するイベントであればこちらが、Issueのコメントに対するイベントであればこちらとなります。
また、「何が起きるか」については単純にスクリプトを書いていけばいいのですが、GitHubのAPIについては@octokit/restによる操作が可能です。
詳細な定義はこちらを参照してください。
context.github
がoctokitのインスタンスとなります。
GitHubのリポジトリに作成したBotをインストールする
https://github.com/settings/apps/${xxxxx}/installations から作成したBotをインストールできます。${xxxxx}には作成したアプリ名を指定してください。
Installをクリックし、Botの適用範囲を指定します。
インストールできました。
起動する
以下でローカルにBotを起動できます。
$ npm run dev
起動した状態で、指定したリポジトリのIssueをラベル未指定のまま閉じてみます。
BotによるIssueへのコメントとIssueのオープンが確認できました。
Glitchにデプロイする
ProbotのチュートリアルではGlitch、Heroku、Nowへのデプロイがそれぞれ紹介されていますが、ここではGlitchへデプロイしてみます。
BotをGitHubのリポジトリに追加する
Glitchでデプロイする際にGitHub経由でアプリケーションを送るため、作成したBotをGitHubのリポジトリに追加します。
$ git remote add inabajunmr https://github.com/inabajunmr/test-inaba $ git add . $ git commit -m "initial" $ git push --set-upstream inabajunmr master
Glitchの設定
こちらからGlitchのプロジェクトを作成します。GitHubアカウントでのサインインが可能です。
Advanced OptionsからGitHubへのアクセス権限を追加し、Import from GitHubでBotのリポジトリをインポートします。
リポジトリを指定します。
インポートできました。
プロジェクトの名前を変更します。
.env
ファイルを編集します。
APP_ID=12729 WEBHOOK_SECRET=XXXX PRIVATE_KEY_PATH=.data/private-key.pem NODE_ENV=production
APP_IDはローカルで指定した.env
の内容と同様です。
WEBHOOK_SECRETは以下のコマンドで生成した値を指定しました。
$ openssl rand -base64 32
.data/private-key.pem
を作成します。ファイルに先ほどダウンロードした秘密鍵をコピペします。
Showをクリックすると、デプロイされたアプリケーションにアクセスできます。
GitHub Appsの再設定
以下のURLからBotの設定画面を再度開きます。${xxxxx}には作成したアプリ名を指定してください。 https://github.com/settings/apps/${xxxxx}
先ほどdevelopment
と指定したWebhook secretに、新しく生成した値を指定し直します。
また、Webhook URLにGlitchのURLを指定します。今回の場合、https://test-inaba.glitch.meとなります。ShowからアクセスできるアプリケーションのURLから、/probot
を無くしたものがWebhook
URLとなります。
設定が完了したので、再度GitHubにてテストしたところ正常に動作することが確認できました。
まとめ
ProbotはGitHub Appsを作成するためのフレームワークです。
主な機能として、
- GitHubのWebHookから送信された各イベントに対する処理
- GitHubのAPI実行
を簡潔に記載することができます。
ProbotでGitHubのBotを作成し、Glitchでデプロイしてみました。 Probotの設定および実装は非常にシンプルにできており、Botの実装が簡単に行えそうです。
私からは以上です。